package br.unifesp.lma.chamada.controller.web;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import br.unifesp.lma.chamada.dao.AlunoDAO;
import br.unifesp.lma.chamada.dao.AulaDAO;
import br.unifesp.lma.chamada.dao.DisciplinaDAO;
import br.unifesp.lma.chamada.dao.NotasDAO;
import br.unifesp.lma.chamada.dao.ProfessorDAO;
import br.unifesp.lma.chamada.model.embed.AlunoDisciplina;
import br.unifesp.lma.chamada.model.embed.Nota;
import br.unifesp.lma.chamada.model.entity.Aluno;
import br.unifesp.lma.chamada.model.entity.Disciplina;
import br.unifesp.lma.chamada.model.entity.Notas;

@RequestMapping(value = "/web")
@Controller
public class NotaController {

	private static Logger log = Logger.getLogger(NotaController.class);

	@Autowired
	private AlunoDAO alunoDAO;

	@Autowired
	private ProfessorDAO professorDAO;

	@Autowired
	private NotasDAO notasDAO;

	@Autowired
	private DisciplinaDAO disciplinaDAO;

	@Autowired
	private AulaDAO aulaDAO;

	@RequestMapping(value = "cadastrar-notas", method = RequestMethod.GET)
	public String cadastrarNotas(Model uiModel, Long disciplinaId) {
		Disciplina disciplina = disciplinaDAO.get(disciplinaId);

		List<Aluno> alunos = alunoDAO.get(getAlunosIds(disciplina.getAlunos()));
		if (alunos.size() > 0) {
			Double[][] provas = new Double[alunos.size()][disciplina.getQtdProvas()];
			Double[][] trabalhos = new Double[alunos.size()][disciplina.getQtdTrab()];
			Double[] medias = new Double[alunos.size()];

			for (int i = 0; i < alunos.size(); i++) {
				AlunoDisciplina alunoDisciplina = obterAlunoDisciplina(alunos.get(i), disciplina);
				if (alunoDisciplina != null) {

					if (alunoDisciplina.getNotasId() != null) {

						Notas notas = notasDAO.get(alunoDisciplina.getNotasId());

						if (notas.getProvas() != null) {
							for (int j = 0; j < disciplina.getQtdProvas(); j++) {

								List<Nota> provas2 = notas.getProvas();

								for (Nota nota : provas2) {
									if (nota.getPosicao() == j) {
										provas[i][j] = nota.getNota();
									}
								}

							}
						}

						if (notas.getTrabalhos() != null) {
							for (int j = 0; j < disciplina.getQtdTrab(); j++) {
								List<Nota> trabalhos2 = notas.getTrabalhos();

								for (Nota nota : trabalhos2) {
									if (nota.getPosicao() == j) {
										trabalhos[i][j] = nota.getNota();
									}
								}
							}
						}
					}
				}
			}

			for (int i = 0; i < medias.length; i++) {
				Double mediaTrabalho = 0.0, mediaProva = 0.0;

				for (int j = 0; j < provas[i].length; j++) {
					if (provas[i][j] != null) {
						mediaProva += provas[i][j];
					}
				}
				mediaProva /= provas[i].length;

				for (int j = 0; j < trabalhos[i].length; j++) {
					if (trabalhos[i][j] != null) {
						mediaTrabalho += trabalhos[i][j];
					}
				}

				mediaTrabalho /= trabalhos[i].length;

				medias[i] = (mediaProva * disciplina.getPesoProvas() + mediaTrabalho * disciplina.getPesoTrab())
						/ (disciplina.getPesoProvas() + disciplina.getPesoTrab());
			}

			uiModel.addAttribute("provas", provas);
			uiModel.addAttribute("trabalhos", trabalhos);
			uiModel.addAttribute("medias", medias);
		}
		uiModel.addAttribute("disciplinaId", disciplinaId);
		uiModel.addAttribute("alunos", alunos);
		uiModel.addAttribute("active", "disciplinas");
		uiModel.addAttribute("disciplina", disciplina);

		return "form-notas";
	}

	@RequestMapping(value = "salvar-notas", method = RequestMethod.POST)
	public String salvarNotas(Model uiModel, ServletRequest request, Long disciplinaId) {
		HttpServletRequest httpRequest = (HttpServletRequest) request;

		Disciplina disciplina = disciplinaDAO.get(disciplinaId);
		List<Aluno> alunos = alunoDAO.get(getAlunosIds(disciplina.getAlunos()));

		Double provas[][] = new Double[alunos.size()][disciplina.getQtdProvas()];
		Double trabalhos[][] = new Double[alunos.size()][disciplina.getQtdTrab()];

		preencherVetores(httpRequest, disciplina, alunos, provas, trabalhos);
		salvarValoresNosObjetos(disciplina, alunos, provas, trabalhos);

		disciplinaDAO.put(disciplina);

		return "redirect:/web/cadastrar-notas?disciplinaId=" + disciplinaId;
	}

	private List<Long> getAlunosIds(List<AlunoDisciplina> alunos) {
		List<Long> result = new ArrayList<Long>();
		for (AlunoDisciplina alunoDisciplina : alunos) {
			result.add(alunoDisciplina.getIdAluno());
		}
		return result;
	}

	private void salvarValoresNosObjetos(Disciplina disciplina, List<Aluno> alunos, Double[][] provas, Double[][] trabalhos) {
		for (int i = 0; i < alunos.size(); i++) {
			AlunoDisciplina alunoDisciplina = obterAlunoDisciplina(alunos.get(i), disciplina);
			if (alunoDisciplina == null) {
				alunoDisciplina = new AlunoDisciplina();
				alunoDisciplina.setIdAluno(alunos.get(i).getId());
				disciplina.getAlunos().add(alunoDisciplina);

			}

			Notas notas;
			if (alunoDisciplina.getNotasId() == null) {
				notas = new Notas();
			} else {
				notas = notasDAO.get(alunoDisciplina.getNotasId());
			}

			for (int j = 0; j < disciplina.getQtdProvas(); j++) {
				List<Nota> provas2 = notas.getProvas();
				boolean encontrou = false;
				for (Nota nota : provas2) {
					if (nota.getPosicao() == j) {
						nota.setNota(provas[i][j]);
						encontrou = true;
					}
				}

				if (!encontrou) {
					Nota nota = new Nota();
					nota.setPosicao(j);
					nota.setNota(provas[i][j]);
					notas.getProvas().add(nota);
				}
			}

			for (int j = 0; j < disciplina.getQtdTrab(); j++) {
				List<Nota> trabalhos2 = notas.getTrabalhos();
				boolean encontrou = false;
				for (Nota nota : trabalhos2) {
					if (nota.getPosicao() == j) {
						nota.setNota(trabalhos[i][j]);
						encontrou = true;
					}
				}

				if (!encontrou) {
					Nota nota = new Nota();
					nota.setPosicao(j);
					nota.setNota(trabalhos[i][j]);
					notas.getTrabalhos().add(nota);
				}
			}

			notasDAO.put(notas);
			alunoDisciplina.setNotasId(notas.getId());
		}
	}

	private AlunoDisciplina obterAlunoDisciplina(Aluno aluno, Disciplina disciplina) {
		List<AlunoDisciplina> alunos = disciplina.getAlunos();

		for (AlunoDisciplina alunoDisciplina : alunos) {
			if (alunoDisciplina.getIdAluno().equals(aluno.getId())) {
				return alunoDisciplina;
			}
		}

		return null;

	}

	private void preencherVetores(HttpServletRequest httpRequest, Disciplina disciplina, List<Aluno> alunos, Double[][] provas,
			Double[][] trabalhos) {
		for (int i = 0; i < alunos.size(); i++) {
			for (int j = 0; j < disciplina.getQtdProvas(); j++) {
				String parameter = httpRequest.getParameter("provas[" + i + "][" + j + "]");
				try {
					Double nota = Double.parseDouble(parameter);
					provas[i][j] = nota;
				} catch (Exception ex) {
					provas[i][j] = 0.0;
				}
			}
		}

		for (int i = 0; i < alunos.size(); i++) {
			for (int j = 0; j < disciplina.getQtdTrab(); j++) {
				String parameter = httpRequest.getParameter("trabalhos[" + i + "][" + j + "]");
				try {
					parameter = parameter.replace(",", ".");
					Double nota = Double.parseDouble(parameter);
					trabalhos[i][j] = nota;
				} catch (Exception ex) {
					trabalhos[i][j] = 0.0;
				}
			}
		}
	}

}
